﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Twodi.Input
{
    /// <summary>
    /// Objeto que contem informações de input do teclado, utilizando dois estados como meio de controle.
    /// </summary>
    public class KeyboardInput : GameComponent
    {
        /// <summary>
        /// Estados do Teclado.
        /// </summary>
        private static KeyboardState keyboardState, oldKeyboardState;

        /// <summary>
        /// Construtor do Controlador do Teclado.
        /// </summary>
        /// <param name="game">Game associado ao Controlador.</param>
        public KeyboardInput(Game game)
            : base(game)
        {
            keyboardState = Keyboard.GetState();
        }

        /// <summary>
        /// Atualizar estados do teclado.
        /// </summary>
        /// <param name="gameTime">Tempo do jogo atual.</param>
        public override void Update(GameTime gameTime)
        {
            oldKeyboardState = keyboardState;
            keyboardState = Keyboard.GetState();
            base.Update(gameTime);
        }

        /// <summary>
        /// Trocar estados.
        /// </summary>
        private void swapStates()
        {
            oldKeyboardState = keyboardState;
        }

        /// <summary>
        /// Alguma tecla pressionada.
        /// </summary>
        public bool isAnyKeyPressed
        {
            get
            {
                return (keyboardState.GetPressedKeys().Length > 0);
            }
        }

        /// <summary>
        /// Tecla Esc foi pressionada e solta.
        /// </summary>
        public bool Escape
        {
            get
            {
                return isKeyPressed(Keys.Escape);
            }
        }

        /// <summary>
        /// Tecla Enter foi pressionada e solta.
        /// </summary>
        public bool Enter
        {
            get
            {
                return isKeyPressed(Keys.Enter);
            }
        }


        /// <summary>
        /// Tecla Enter esta sendo pressionada.
        /// </summary>
        public bool Pressing_Enter
        {
            get
            {
                return isKeyDown(Keys.Enter);
            }
        }

        /// <summary>
        /// Tecla Espaço foi pressionada e solta.
        /// </summary>
        public bool Space
        {
            get
            {
                return isKeyPressed(Keys.Space);
            }
        }

        /// <summary>
        /// Tecla Espaço esta sendo pressionada.
        /// </summary>
        public bool Pressing_Space
        {
            get
            {
                return isKeyDown(Keys.Space);
            }
        }

        /// <summary>
        /// Seta para esquerda foi pressionada e solta.
        /// </summary>
        public bool Left
        {
            get
            {
                return isKeyPressed(Keys.Left);
            }
        }

        /// <summary>
        /// Seta para direita foi pressionada e solta.
        /// </summary>
        public bool Right
        {
            get
            {
                return isKeyPressed(Keys.Right);
            }
        }

        /// <summary>
        /// Seta para cima foi pressionada e solta.
        /// </summary>
        public bool Up
        {
            get
            {
                return isKeyPressed(Keys.Up);
            }
        }

        /// <summary>
        /// Seta para baixo foi pressionada e solta.
        /// </summary>
        public bool Down
        {
            get
            {
                return isKeyPressed(Keys.Down);
            }
        }

        /// <summary>
        /// Seta para esquerda esta sendo pressionada.
        /// </summary>
        public bool LeftPressed
        {
            get
            {
                return isKeyDown(Keys.Left);
            }
        }

        /// <summary>
        /// Seta para direita esta sendo pressionada.
        /// </summary>
        public bool RightPressed
        {
            get
            {
                return isKeyDown(Keys.Right);
            }
        }

        /// <summary>
        /// Seta para cima esta sendo pressionada.
        /// </summary>
        public bool UpPressed
        {
            get
            {
                return isKeyDown(Keys.Up);
            }
        }

        /// <summary>
        /// Seta para baixo esta sendo pressionada.
        /// </summary>
        public bool DownPressed
        {
            get
            {
                return isKeyDown(Keys.Down);
            }
        }

        /// <summary>
        /// Tecla foi pressionada e agora esta solta.
        /// </summary>
        /// <param name="key">Tecla.</param>
        /// <returns></returns>
        public bool isKeyUp(Keys key)
        {
            return keyboardState.IsKeyUp(key) && oldKeyboardState.IsKeyDown(key);
        }

        /// <summary>
        /// Tecla esta sendo pressionada.
        /// </summary>
        /// <param name="key">Tecla.</param>
        /// <returns></returns>
        public bool isKeyDown(Keys key)
        {
            return keyboardState.IsKeyDown(key);
        }

        /// <summary>
        /// Tecla foi pressionada e solta.
        /// </summary>
        /// <param name="key">Tecla.</param>
        /// <returns></returns>
        public bool isKeyPressed(Keys key)
        {
            return keyboardState.IsKeyDown(key) && oldKeyboardState.IsKeyUp(key);
        }

        /// <summary>
        /// Tecla foi pressionada e solta com alguma tecla de alteração.
        /// </summary>
        /// <param name="alterKey">Tecla de alteração (Shift, Alt, Ctrl...).</param>
        /// <param name="key">Tecla.</param>
        /// <returns></returns>
        public bool isAlterKeyPressed(Keys alterKey, Keys key)
        {
            return isKeyDown(alterKey) && isKeyPressed(key);
        }

        /// <summary>
        /// Tecla foi solta com alguma tecla de alteração.
        /// </summary>
        /// <param name="alterKey">Tecla de alteração (Shift, Alt, Ctrl...).</param>
        /// <param name="key">Tecla.</param>
        /// <returns></returns>
        public bool isAlterKeyUp(Keys alterKey, Keys key)
        {
            return isKeyDown(alterKey) && isKeyUp(key);
        }

        /// <summary>
        /// Tecla esta sendo pressionada com alguma tecla de alteração.
        /// </summary>
        /// <param name="alterKey">Tecla de alteração (Shift, Alt, Ctrl...).</param>
        /// <param name="key">Tecla.</param>
        /// <returns></returns>
        public bool isAlterKeyDown(Keys alterKey, Keys key)
        {
            return isKeyDown(alterKey) && isKeyDown(key);
        }
    }
}
